use crate::trafic::Trafic;

mod trafic {
    pub enum TraficLight {
        Red,
        Yellow,
        Green,
    }

    pub trait Trafic {
        fn time(&self) -> u32;
    }

    impl Trafic for TraficLight {
        fn time(&self) -> u32 {
            match self {
                TraficLight::Red => 20,
                TraficLight::Yellow => 3,
                TraficLight::Green => 30,
            }
        }
    }
}

mod fn_excise {
    pub fn sum_array(array: &[u32]) -> Option<u32> {
        let mut sum: Option<u32> = Some(0);
        for i in array {
            if let None = sum {
                break;
            }
            sum = sum.unwrap().checked_add(*i);
        }
        sum
    }
}

mod geometry {

    pub struct Retangle {
        pub x: f64,
        pub y: f64,
    }

    pub struct Circle{
        pub r:f64,
    }

    pub trait Geo {
        fn cal_area(&self) -> Result<f64, String>;
    }

    impl Geo for Circle{
        fn cal_area(&self) -> Result<f64, String> {
            let area = 3.14*self.r*self.r;
            Ok(area)
        }
    }

    impl Geo for Retangle {
        fn cal_area(&self) -> Result<f64, String> {
            Ok(self.x * self.y)
        }
    }

    pub fn print_area<T>(t: &T)
    where
        T: Geo,
    {
        let area = t.cal_area();
        match area {
            Ok(v) => println!("area is {}", v),
            Err(e) => println!("error is {:?}", e),
        }
    }
}

fn main() {
    //打印不同颜色灯的等待时间
    println!("red wait time is {}",trafic::TraficLight::Red.time());
    println!("Yellow wait time is {}",trafic::TraficLight::Yellow.time());
    println!("Green wait time is {}",trafic::TraficLight::Green.time());

    //计算数组求和
    let a:&[u32] = &[13,15,20];
    println!("array sum is {:?}",fn_excise::sum_array(a));

    //计算面积
    let retangle = geometry::Retangle{x:40.0,y:20.0};
    geometry::print_area(&retangle);

    let circle = geometry::Circle{r:5.0};
    geometry::print_area(&circle);
}

